﻿#include "IApiService.h"
#include <QFile>
#include <QDebug>
#include <QJsonDocument>
#include <QJsonArray>
#include <QJsonObject>
#include <QDir>
#include "PluginManager.h"
#include "AESAlgorithm.h"

using namespace CVV::Interface;

IApiService::IApiService(const QString &serviceCode, bool bIsAlgCall, QObject *parent)
    : QObject(parent)
    , m_bIsAlgCall(bIsAlgCall)
    , m_strServiceCode(serviceCode)
{
    m_runStatusList.clear();

    QString pluginPath = "./plugins";
#ifdef Q_OS_LINUX
    pluginPath = QDir::homePath() + "/micro-i/vision_algorithms/cvvision_depends/libs/plugins";
#endif
    //1.加载所有插件
    if (CVV::Infrastructure::ExtensionSystem::PluginManager::allObjects().isEmpty())
    {
        qDebug() << __FUNCTION__ << "reload plugins";
        CVV::Infrastructure::ExtensionSystem::PluginManager::clearPlugin();
        CVV::Infrastructure::ExtensionSystem::PluginManager::setPluginPaths(QStringList()<< pluginPath);
        CVV::Infrastructure::ExtensionSystem::PluginManager::loadPlugins();
    }

    load();
}

IApiService::~IApiService()
{
    qDebug() << __FUNCTION__ << m_enginMaps.size() << ", m_enginMaps delete";

    clearEngine();
}

void IApiService::slotRunStatus(const RunStatus runStatus, const QString engineKey)
{
    m_runStatusList[engineKey] = runStatus;
}


void IApiService::registerDebugEngine(const QList<IEngine*> &engine)
{
    m_enginMaps.insert("Debug", engine);
}

QList<IEngine*> IApiService::getEngine(const QString &engineKey)
{
    if(m_enginMaps.contains(engineKey))
    {
        return m_enginMaps[engineKey];
    }

    return  QList<IEngine*>();
}

void IApiService::clearEngine()
{
    for (auto &lstEngine : m_enginMaps)
    {
        qDeleteAll(lstEngine);
        lstEngine.clear();
    }

    m_enginMaps.clear();
}

IApiService::RunStatus IApiService::runStatus(const QString engineKey) const
{
    if(m_runStatusList.find(engineKey) == m_runStatusList.end())
    {
        return stop;
    }

    return m_runStatusList[engineKey];
}

void IApiService::setRunStatus(RunStatus newRunStatus, const QString engineKey)
{
    m_runStatusList[engineKey] = newRunStatus;
}

bool IApiService::load()
{
    QString strConfigName = "sconfig.json";
    if (m_bIsAlgCall)
    {
        strConfigName = "alg_sconfig.json";
    }
    m_planDomMaps.clear();
    m_generalDomMaps.clear();
    m_visualGuidanceDomMaps.clear();
    QString defaultPath = QDir::homePath() + "/micro-i/vision_algorithms/cvv/";
    QString exePath = "./cvv/";
    QFile oFile(defaultPath + strConfigName);
    QString usePath;
    if (!oFile.exists())
    {
        oFile.setFileName(exePath + strConfigName);
        if (!oFile.exists())
        {
            qWarning() << "sconfig.json not exists";
            return false;
        }else{
            usePath = exePath;
        }
    }else{
        usePath = defaultPath;
    }

    if (!oFile.open(QIODevice::ReadOnly))
    {
        qWarning() << "sconfig.json open failed";
        return false;
    }

    QJsonParseError jsError;
    QJsonDocument doc = QJsonDocument::fromJson(oFile.readAll(), &jsError);
    if (jsError.error != QJsonParseError::NoError)
    {
        oFile.close();
        qWarning() << jsError.errorString();
        return false;
    }

    oFile.close();
    if (doc.isArray())
    {
        QJsonArray jsAry = doc.array();
        for (auto ary : jsAry)
        {
            if (ary.isObject())
            {
                QJsonObject jsObject = ary.toObject();

                QString strProfileProductId = jsObject.value("profileProductId").toString();
                QStringList lstProfileProductId = strProfileProductId.split(",");
                //                int profileProductId = jsObject.value("profileProductId").toInt();
                QJsonArray buttonAry = jsObject.value("schemeMap").toArray();
                for (auto btnObj : buttonAry)
                {
                    QJsonObject btnObject = btnObj.toObject();
                    int pictureId = btnObject.value("pictureId").toInt();

                    // 图片对应的方案列表
                    QJsonArray schemeAry = btnObject.value("schemes").toArray();
                    for (auto sAry : schemeAry)
                    {
                        QJsonObject schemeObject = sAry.toObject();
                        QString serviceCode = schemeObject.value("serviceCode").toString();
                        if (!serviceCode.isEmpty()
                                && !m_strServiceCode.isEmpty()
                                && serviceCode != m_strServiceCode)
                        {
                            continue;
                        }

                        int defectCode = schemeObject.value("defectCode").toInt();
                        QString schemeName = schemeObject.value("schemeName").toString();
                        QString schemeType = schemeObject.value("schemeType").toString();
                        QString cvvpath = QString("%1schemes/%2").arg(usePath).arg(schemeName);
                        QFile xml(cvvpath);
                        if (xml.exists())
                        {
                            if (!xml.open(QIODevice::ReadOnly))
                            {
                                qWarning() << cvvpath << " open failed";
                                xml.close();
                                return false;
                            }

                            QByteArray ciphertextArr = xml.readAll();
                            xml.close();
                            QDomDocument doc;
                            if (doc.setContent(ciphertextArr, false))
                            {
                                for (auto strId : lstProfileProductId)
                                {
                                    int profileProductId = strId.toInt();
                                    QString key = QString("%1-%2")
                                            .arg(profileProductId)
                                            .arg(pictureId);

                                    if (m_strServiceCode == "general")
                                    {
                                        m_generalDomMaps[key][schemeType].push_back(doc);
                                    }
                                    else if (m_strServiceCode == "VisualGuidance")
                                    {
                                        m_visualGuidanceDomMaps[key].push_back(doc);
                                    }
                                    else
                                    {
                                        m_planDomMaps[key].push_back(doc);
                                    }
                                }
                            }
                            else if (!ciphertextArr.isEmpty())// 解密
                            {
                                QByteArray contentArr = QByteArray::fromStdString(gAESAlgorithm->cbcDecrypt(ciphertextArr.toStdString(), ""));
                                if(!contentArr.isEmpty() && doc.setContent(contentArr, false))
                                {
                                    for (auto strId : lstProfileProductId)
                                    {
                                        int profileProductId = strId.toInt();
                                        QString key = QString("%1-%2")
                                                .arg(profileProductId)
                                                .arg(pictureId);

                                        if (m_strServiceCode == "general")
                                        {
                                            m_generalDomMaps[key][schemeType].push_back(doc);
                                        }
                                        else
                                        {
                                            m_planDomMaps[key].push_back(doc);
                                        }
                                    }
                                }
                                else
                                {
                                    qWarning() << cvvpath + " decryption failed";
                                }
                            }
                            else
                            {
                                qWarning() << cvvpath + " is empty";
                            }
                        }
                        else
                        {
                            qWarning() << cvvpath << " not exists";
                        }
                    }
                }

            }
        }
    }
    qDebug()<<"load sconfig success!";
    return true;
}
